#ifndef _VISTAGTKMM_H
#define	_VISTAGTKMM_H

#include <vector>
#include <math.h>
#include <iostream>
#include "../Modelo/Primitiva.h"
#include "../Modelo/Punto.h"
#include "../Modelo/Linea.h"
#include "../Modelo/Rectangulo.h"
#include "../Modelo/Triangulo.h"
#include "../Modelo/Circulo.h"
#include "../Vista/Vista.h"
#include "../Modelo/Modelo.h"
#include "../Modelo/Conjunto.h"
#include "../Modelo/Historial.h"
#include "ImagenGtkmm.h"

#include <gtkmm-2.4/gtkmm.h>
#include <gdkmm-2.4/gdkmm.h>
#include <sigc++-2.0/sigc++/sigc++.h>
#include <cairo/cairo.h>

using namespace std;

/*    BOTONES      */
//Primitivas
const int PUNTO = 0;
const int LINEA = 1;
const int CIRCULO = 2;
const int TRIANGULO = 3;
const int RECTANGULO = 4;
const int IMAGEN = 5;

//Herramientas
const int SELECT = 6;
const int COPY = 7;
const int PASTE = 8;
const int DUP = 9;
const int CUT = 10;
const int DELETE = 11;
const int GROUP = 12;
const int UNGROUP = 13;
const int ROTATE = 14;
const int PICK_COLOR = 15;
const int UNDO = 16;
const int REDO = 17;

//Tipo de Acción
const int NORMAL = 0;
const int MOVIMIENTO = 1;

#define PI 3.14159265

//Typedef para el Builder de Glade
typedef Glib::RefPtr<Gtk::Builder> xmlref_t;

class Ventana : public Vista
{
    public:
        Ventana(xmlref_t refXml);
        ~Ventana();
        void PonerModelo(Modelo *m) { Vista::PonerModelo(m); Historial *nuevo = new Historial(m); historial.push_back(nuevo); };

        void addPunto(Punto*);
        void addLinea(Punto*, int);
        void addRec(Punto*, int, bool selectionRect = false);
        void addCirc(Punto*, int);
        void addTri(Punto*, int);
        void addImage(Punto*);

        bool seleccionContienePunto(const Punto&);
        bool seleccionContieneLinea(Linea *);
        bool seleccionContieneRectangulo(Rectangulo *);
        bool seleccionContieneTriangulo(Triangulo *);
        bool seleccionContieneCirculo(Circulo *);
        bool seleccionContieneConjunto(Conjunto *);
        bool seleccionContieneImagen(ImagenGtkmm *);

        void pinta();
        void pintaFiguras(vector<Primitiva*>);
        void seleccionarFiguras();
        void moverFigurasSeleccionadas(vector<Primitiva*>, int, int);
        void eliminarFigurasSeleccionadas();
        bool resetearPaint(GdkEventButton*);
        void cargarImagenes();
        
        bool guardarAFichero(GdkEventButton*);
        bool mostrarAbout(GdkEventButton*);
        void guardarCambiosAutoSave();
        bool mostrarAutoSave(GdkEventButton*);
        bool on_autosave();
        bool cargarArchivo(GdkEventButton*);
        bool guardarArchivoComo(GdkEventButton*);
        
        virtual void Actualizar() { cout << "Actualizo\n";};

        /* Eventos */
        bool on_salir_clicked(GdkEventButton *b);
        bool expose_event(GdkEventExpose *e);
        bool motion_notify_event(GdkEventMotion *e);
        bool button_press_event(GdkEventButton *e);
        bool button_release_event(GdkEventButton *e);
        bool mover_rueda(GdkEventScroll*);
        bool key_press_event(GdkEventKey*);
        bool key_release_event(GdkEventKey*);

        /* Callbacks */
        
        void clickPunto() { boton_actual = PUNTO;};
        void clickLinea() { boton_actual = LINEA;};
        void clickRec() { boton_actual = RECTANGULO;};
        void clickTri() { boton_actual = TRIANGULO;};
        void clickCirc() { boton_actual = CIRCULO;};
        void clickImage(){ boton_actual = IMAGEN;};
        
        void clickSelect() { boton_actual = SELECT; };
        void clickCopy();
        void clickPaste();
        void clickDup();
        void clickCut();
        void clickDelete() { boton_actual = DELETE; eliminarFigurasSeleccionadas(); };
        void clickGroup();
        void clickUngroup();
        void clickRotate() { boton_actual = ROTATE; labelState->set_text("Mueva la rueda del ratón para rotar la figura."); };
        void clickPickColor();
        void clickUndo();
        void clickRedo();

    private:
        Gtk::Window* dialogoAutoGuardado;
        Gtk::Window* about;
        Gtk::SpinButton* spinbuttonAutoGuardado;
        Gtk::DrawingArea* drawArea;         //DrawingArea que será donde pintaremos
        Gtk::Label* labelState;             //Etiqueta donde se informa de la acción a realizar
        Gdk::Color color_actual;
        Cairo::RefPtr<Cairo::Context> cairo;   //Contexto gráfico(Cairo) para dibujar

        bool rotar, redimensionar;
        int boton_actual;
        int accion;
        int movX, movY;
        int tiempo_auto_guardado;
        int historial_actual;
        double factor_escalado;
        
        sigc::connection conexion;          //Conexión empleada para el bucle de autoguardado

        Rectangulo* recSeleccion;           //Recuadro de selección

        vector<Historial*> historial;
};

#endif	/* _VISTAGTKMM_H */